//
//  SLPagerLocker.m
//  SLPagerView
//
//  Created by l.t.zero on 2022/1/8.
//

#import "SLPagerLocker.h"
#import <pthread.h>

#define _sl_macro_concat(a, b) a##b
#define sl_macro_concat(a, b) _sl_macro_concat(a, b)

typedef void(^sl_defer_block_t)(void);
NS_INLINE __unused void sl_deferFunc(__strong sl_defer_block_t *blockRef){
    sl_defer_block_t actualBlock = *blockRef;
    actualBlock();
}

// the core macro

#define sl_defer(deferBlock) \
autoreleasepool {}\
__strong sl_defer_block_t SL_macro_concat(__SL_stack_defer_block_, __LINE__) __attribute__((cleanup(sl_deferFunc), unused)) = deferBlock

@implementation SLPagerLocker{
    pthread_mutex_t _lock; // recursive lock
}

- (void)dealloc{
    pthread_mutex_destroy(&_lock);
}

- (instancetype)init{
    
    if (self = [super init]){
        pthread_mutexattr_t attr;//互斥锁
        pthread_mutexattr_init (&attr);//初始化互斥锁
        pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
        pthread_mutex_init (&_lock, &attr);
        pthread_mutexattr_destroy (&attr);
    }
    
    return self;
}

- (void)lock{
    pthread_mutex_lock(&self->_lock);
}
- (void)unlock{
    pthread_mutex_unlock(&self->_lock);
}
- (BOOL)perform:(void (^)(void))block{
    pthread_mutex_lock(&self->_lock);
    if(block){
        block();
    }
    pthread_mutex_unlock(&self->_lock);
    return YES;
}
@end
